/*!
\file Parameters.qml
\brief Application parameters definition

This component contains all the application parameters, used to manage the graphic elements
of the interface in a totally relative way defined as Adaptive Technology \n
For more informations, refers to page \ref Adaptive_Interface

\author © 2011 Enrico Miglino / Tech Consulting (enrico.miglino@ovi.com)
\author "Black Cat Cutting Studio" is protected by the copyright law
\author Distributed under the LGPL 3.0 license.
\version 1.0 alpha
\date 2011

\par Black Cat Cutting Studio licensing notes

    "Black Cat Cutting Studio" is free software: you can redistribute it
    and/or modify it under the terms of the Lesser GNU General Public License
    as published by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    "Black Cat Cutting Studio" is distributed in the hope that it
    will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    Lesser GNU General Public License for more details.

    You should have received a copy of the Lesser GNU General Public License
    along with "Black Cat Cutting Studio".
    If not, see <http://www.gnu.org/licenses/>.

\page Adaptive_Interface The Adaptive Interface
\note [Draft 0.1] Adaptive interface is developed as its first version,
so the lineguides about this layout strategy are subject to frequent modifications.
Next versions of this application can contain updated informations on the development notes on the
\c Adaptive \c Interface tecnology.

Things that will change are the fixed value properties. These values should be
managed through an external xml file that can be reconfigured without recompile.

\section sec0 QML Anchors and Margins
Qml language features supports a set of properties for the graphic elements so that they can be
set on the screen (formerly the viewer surface). This means that a graphic element can be positioned
\e relative to another element, defining \b anchors and \b margins.
This is useful in cases where the same object will be replicated e.g. in a buttons toolbar.

But these features can't cover all the needs to manage the viewer in a parametrized way.

\section sec1 Going Ahead
\c Adaptive \c interface can place every element somewhere in a \b virtual \b layout independently by the screen dimensions.
In few words this means that is possible to create a layout defining only the relations between the objects. \n
The fixed properties defined in the configuration section of the application are as less as possible,
while all the objects are set on the viewer using dynamic methods to calculate the perceptive position of every
elements with a \b percentage \b relation between the components and the viewer area. \n
This method can be applied recursively to the nested objects, but it is mostly required at the first level interface.

\section sec2 Advantages
The \c Qt \c declarative \c view has two different methods to manage the relations between the view and the screen:
\code
QDeclarativeView::SizeRootObjectToView
\endcode

and

\code
QDeclarativeView::SizeViewToRootObject
\endcode

Thus, setting the view to be resized to the physical screen (or window)

\code
viewer.setResizeMode(QDeclarativeView::SizeRootObjectToView);
\endcode

the Qml program resizes the interface to the dimensions of the window or the screen when the windows is
opened at full screen.
This is useful when the view will be shown on screens with different resolutions
(i.e. the small screens of the smartphones)

The advantage adopting the Adaptive Interface method is that you don't need to setup
any fixed value: all layout position and sizing parameters are managed byt methods of
the \c parameters object. Every change in the viewer dimensions - including the aspect ratio -
influences the layout elements moved and sized in the right viewer position.

\subsection sec1_1 Objects Scaling Limit
\note Take in advance that the best results to manage an interface layout based on Adaptive Interface
is obtained using \b resizable objects. This means that \c .png images and \c .svg vector objects
are to be preferred to jpeg or other kind of non-resizable images.

The methods that dynamically calculate the sizes of the objects
has the role to take care of the \b Object \b Scaling \b Limit \n
If we consider for example a png image to be used as a button, we can't indefinitely change
its size whitout loose the usability of the button itself. Thus, for this object there is
a min and Max size limit that can't be exceeded.
The the calculation methods take care of these values and when the percentage scaling exceed,
the button management method changes.

\subsection sec1_2 Objects Management Methods
First, we should consider as \b objects those final compound elements that are layed out on the viewer.
This means that if our layout shows a toolbar with five buttons, anchored side by side, when the scaling
factor became too small the scaling factor is not applied and the toolbar is partially shown
in the viewer while the horizontal sliding property is activated.

*/
import QtQuick 1.0

// The global properties of the program.
Item {
    id: globalproperties

    // Splash image screen percentage
    property real splashResize: 0.5

    /*
     The real value for the default screen sizes is assigned at runtime, taken
     from the viewer size. The initial assigned values are used only as a default
     that should be overwritten.
     */
    property int defaultScreenWidth: 800
    property int defaultScreenHeight: 480

    /*
    Percentage side spaces used for screen areas
    The number of defined sidespaces on the screen depends on the layout structure
    of the application. All values are expressed in relative percentage of the
    full viewer area.
    */

    // Height of the toolbar on top of the screen
    property real toolbarHeight: 0.04
    // Margins of the toolbar on top of the screen
    property real toolbarMargins: 0.01

    // top notification area height
    property real topControlAreaHeight: 0.14

    // Bottom object sizes
    property real widthRightBottom: 0.20
    property real widthLeftBottom: 0.78
    property real heightRightBottom: 0.35
    property real heightLeftBottom: 0.85

    // Offset percentage for the borders of left bottom area
    property real leftLeftOffset: 0.01
    property real leftBottomOffset: 0.01

    // Offset percentage for the borders of right bottom area
    property real rightRightOffset: 0.02
    property real rightBottomOffset: 0.02

    // ---------------------------------------------------------- START DEBUG BLOCK
    // Debug info.
    // For debug console messages use debugMessage(msg) instead of console.log(msg)
    // in the source module set baseMsg property with the string that should appear
    // before any debug message on the console.
    // To disable debug, set debugStatus to false. This can be done also only in some
    // code blocks.
    property bool debugStatus: true
    property string baseMsg: "*** Debug Parameters: "
    function debugMessage(msg) { if (debugStatus == true) console.log(baseMsg + msg); }
    // ---------------------------------------------------------- END DEBUG BLOCK

    // ---------------------------------------------------------- DYNAMIC VALUES FUNCTIONS

    /*
    [Internal]
    Calculate the size of a block in the viewer.

    The function consider that if the object will be aligned to a borded
    with a space offset, this value influence the final size of the object itself.
    This function is used by all the size calculation functions for the layout
    objects on the viewer.

    calcBlockSize(maxExtension, percArea)
    parameter: maxExtension = viewer size
    parameter: percArea = percentage area occupied by the block
    return result
    */
    function calcBlockSize(maxExtension, percArea, offset) {
        var result;

        // Calculate the relative size as the percentage of the size
        result = (maxExtension * percArea) - (maxExtension * offset);
        return result;
    }


    /*
    Height of the right bottom block of the screen.

    setRightBottomSideHeight()
    return: result
    */
    function setRightBottomSideHeight() {

        return calcBlockSize(globalproperties.defaultScreenHeight,
                             globalproperties.heightRightBottom,
                             globalproperties.rightBottomOffset);
        return result;
    }

    /*
    Height of the left bottom block of the screen.

    setLeftBottomSideHeight()
    return: result
    */
    function setLeftBottomSideHeight() {

        return calcBlockSize(globalproperties.defaultScreenHeight,
                             globalproperties.heightLeftBottom,
                             globalproperties.leftBottomOffset);
        return result;
    }


    /*
    Width of the right bottom block of the screen.

    setRightBottomSideWidth()
    return result
    */
    function setRightBottomSideWidth() {
        var result;

        return calcBlockSize(globalproperties.defaultScreenWidth,
                             globalproperties.widthRightBottom,
                             globalproperties.rightBottomOffset);
        return result;
    }

    /*
    Width of the left bottom block of the screen.

    setLeftBottomSideWidth()
    return result
    */
    function setLeftBottomSideWidth() {
        var result;

        return calcBlockSize(globalproperties.defaultScreenWidth,
                             globalproperties.widthLeftBottom,
                             globalproperties.leftLeftOffset);
        return result;
    }

    /*
     x position of the bottom right-aligned object

     setBottomRightX(barSize)
     parameter: barSize = x object extension
     return: result
     */
    function setBottomRightX(barSize) {
        var result;

        result = globalproperties.defaultScreenWidth -
                barSize -
                (globalproperties.defaultScreenWidth * globalproperties.rightRightOffset);
        return result;
    }

    /*
     x position of the bottom left-aligned object

     setBottomLeftX(barSize)
     parameter: barSize = object width
     return: result
     */
    function setBottomLeftX(barSize) {
        var result;

        result = globalproperties.defaultScreenWidth * globalproperties.leftLeftOffset;
        return result;
    }

    /*
     y position of the bottom right-aligned object

     setBottomRightY(barSize)
     parameter: barSize = y object extension
     return: result
     */
    function setBottomRightY(barSize) {
        var result;

        result = globalproperties.defaultScreenHeight -
                barSize -
                (globalproperties.defaultScreenHeight * globalproperties.rightBottomOffset);
        return result;
    }

    /*
     y position of the bottom left-aligned object

     setBottomLestY(barSize)
     parameter: barSize = y object extension
     return: result
     */
    function setBottomLeftY(barSize) {
        var result;

        result = globalproperties.defaultScreenHeight -
                barSize -
                (globalproperties.defaultScreenHeight * globalproperties.leftBottomOffset);
        return result;
    }

    /*
      Height of the shadowed bar on top of the screen

      setShadowHeight()
      return: result
    */
    function setShadowHeight() {
        var result;

        result = globalproperties.defaultScreenHeight * globalproperties.topControlAreaHeight;
        return result;
    }

    /*
      X axis position of the toolbars

      setToolbarX(barNum)
      parameter: banNum = command set toolbar number
      return: result
    */
    function setToolbarX(barNum) {
        var result;

        switch (barNum) {
        case 1:
            result = globalproperties.defaultScreenWidth * 0.06
            break;
        case 2:
            result = globalproperties.defaultScreenWidth * 0.25
            break;
        case 3:
            result = globalproperties.defaultScreenWidth * 0.32
            break;
        case 4:
            result = globalproperties.defaultScreenWidth * 0.42
            break;
        case 5:
            result = globalproperties.defaultScreenWidth * 0.55
            break;
        default:
            result = 1;
            break;
        }
        return result;
    }

    /*
      Y axis position of the toolbars

      setToolbarY(barNum)
      parameter: banNum = command set toolbar number
      return: result
    */
    function setToolbarY(barNum) {
        var result;

        switch (barNum) {
        case 1:
            result = globalproperties.defaultScreenHeight * 0.01;
            break;
        case 2:
            result = globalproperties.defaultScreenHeight * 0.01;
            break;
        case 3:
            result = globalproperties.defaultScreenHeight * 0.01;
            break;
        case 4:
            result = globalproperties.defaultScreenHeight * 0.01;
            break;
        case 5:
            result = globalproperties.defaultScreenHeight * 0.01;
            break;
        default:
            result = globalproperties.defaultScreenHeight * 0.01;
            break;
        }
        return result;
    }
}

